(function () {
	var parseJSON = function(data) {
		if ( !data || typeof data !== "string") {
			return null;
		}
		// Make sure leading/trailing whitespace is removed (IE can't handle it)
		data = data == null ?  "" : data.toString().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "" )
		// Attempt to parse using the native JSON parser first
		if ( this.JSON && this.JSON.parse ) {
			return this.JSON.parse( data );
		}
		// Make sure the incoming data is actual JSON
		// Logic borrowed from http://json.org/json2.js
		var rvalidchars = /^[\],:{}\s]*$/, 
			rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, 
			rvalidescape = /\\(?:["'\\\/bfnrt]|u[\da-fA-F]{4})/g, 
			rvalidtokens = /(["']?)[^\1\\\r\n]*\1|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g;
		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
					.replace( rvalidtokens, "]" )
					.replace( rvalidbraces, "")) ) {
			return ( new Function( "return " + data ) )();
		}
		//throw new Error("Invalid JSON: " + data );
		return "{error:'Invalid JSON'}";
	};

	if (!this.JSON) {JSON = {};}

    function f(n) {
        return n < 10 ? '0' + n : n;
    }
    if (typeof Date.prototype.toJSON !== 'function') {
        Date.prototype.toJSON = function () {
            return isFinite(this.valueOf())
                ? this.getUTCFullYear()     + '-' +
                    f(this.getUTCMonth() + 1) + '-' +
                    f(this.getUTCDate())      + 'T' +
                    f(this.getUTCHours())     + ':' +
                    f(this.getUTCMinutes())   + ':' +
                    f(this.getUTCSeconds())   + 'Z'
                : null;
        };
        String.prototype.toJSON      =
            Number.prototype.toJSON  =
            Boolean.prototype.toJSON = function () {
                return this.valueOf();
            };
    }
    function a(a) {
        return a != null && a.constructor != null ? Object.prototype.toString.call(a).slice(8, -1) : ""
    }
    var h = {
        trim: function(a) {
            return a.replace(/^[\s\xa0\u3000]+|[\u3000\xa0\s]+$/g, "")
        },
        mulReplace: function(a, b) {
            for (var c = 0; c < b.length; c++) a = a.replace(b[c][0], b[c][1]);
            return a
        },
		escapeChars: function(b) {
			return h.mulReplace(b, [[/\\/g, "\\\\"], [/"/g, '\\"'], [/\r/g, "\\r"], [/\n/g, "\\n"], [/\t/g, "\\t"]])
		}
	};
    var b = h.escapeChars,
    c = {
        isString: function(b) {
            return a(b) == "String"
        },
        isFunction: function(b) {
            return a(b) == "Function"
        },
        isArray: function(b) {
            return a(b) == "Array"
        },
        isArrayLike: function(a) {
            return !! a && typeof a == "object" && a.nodeType != 1 && typeof a.length == "number"
        },
        isObject: function(a) {
            return a !== null && typeof a == "object"
        },
        isPlainObject: function(b) {
            return a(b) == "Object"
        },
        isWrap: function(a, b) {
            return !! a && !!a[b || "core"]
        },
        isElement: function(a) {
            return !! a && a.nodeType == 1
        },
        set: function(a, b, d) {
            if (c.isArray(b)) for (var e = 0; e < b.length; e++) c.set(a, b[e], d[e]);
            else if (c.isPlainObject(b)) for (e in b) c.set(a, e, b[e]);
            else if (c.isFunction(b)) {
                var f = [].slice.call(arguments, 1);
                f[0] = a,
                b.apply(null, f)
            } else {
                var g = b.split(".");
                e = 0;
                for (var h = a,
                i = g.length - 1; e < i; e++) h = h[g[e]];
                h[g[e]] = d
            }
            return a
        },
        get: function(a, b, d) {
            if (c.isArray(b)) {
                var e = [],
                f;
                for (f = 0; f < b.length; f++) e[f] = c.get(a, b[f], d)
            } else {
                if (c.isFunction(b)) {
                    var g = [].slice.call(arguments, 1);
                    return g[0] = a,
                    b.apply(null, g)
                }
                var h = b.split(".");
                e = a;
                for (f = 0; f < h.length; f++) {
                    if (!d && e == null) return;
                    e = e[h[f]]
                }
            }
            return e
        },
        mix: function(a, b, d) {
            if (c.isArray(b)) {
                for (var e = 0,
                f = b.length; e < f; e++) c.mix(a, b[e], d);
                return a
            }
            for (e in b) if (d || !(a[e] || e in a)) a[e] = b[e];
            return a
        },
        dump: function(a, b) {
            var c = {};
            for (var d = 0,
            e = b.length; d < e; d++) if (d in b) {
                var f = b[d];
                f in a && (c[f] = a[f])
            }
            return c
        },
        map: function(a, b, c) {
            var d = {};
            for (var e in a) d[e] = b.call(c, a[e], e, a);
            return d
        },
        keys: function(a) {
            var b = [];
            for (var c in a) a.hasOwnProperty(c) && b.push(c);
            return b
        },
        values: function(a) {
            var b = [];
            for (var c in a) a.hasOwnProperty(c) && b.push(a[c]);
            return b
        },
        create: function(a, b) {
            var d = function(a) {
                a && c.mix(this, a, !0)
            };
            return d.prototype = a,
            new d(b)
        },
        stringify: function(d) {
            if (d == null) return null;
			//if (d && typeof d === 'object' && typeof d.toJSON === 'function') { d = d.toJSON(); }
            d.toJSON && (d = d.toJSON());
            var e = a(d).toLowerCase();
            switch (e) {
            case "string":
                return '"' + b(d) + '"';
            case "number":
            case "boolean":
                return d.toString();
            case "date":
                return "new Date(" + d.getTime() + ")";
            case "array":
                var f = [];
                for (var g = 0; g < d.length; g++) f[g] = c.stringify(d[g]);
                return "[" + f.join(",") + "]";
            case "object":
                if (c.isPlainObject(d)) {
                    f = [];
                    for (g in d) f.push('"' + b(g) + '":' + c.stringify(d[g]));
                    return "{" + f.join(",") + "}"
                }
            }
            return null
        },
        encodeURIJson: function(a) {
            var b = [];
            for (var c in a) {
                if (a[c] == null) continue;
                if (a[c] instanceof Array) for (var d = 0; d < a[c].length; d++) b.push(encodeURIComponent(c) + "=" + encodeURIComponent(a[c][d]));
                else b.push(encodeURIComponent(c) + "=" + encodeURIComponent(a[c]))
            }
            return b.join("&")
        }
    };
	if (typeof JSON.stringify !== 'function') { JSON.stringify = c.stringify; }
	if (typeof JSON.parse !== 'function') { JSON.parse = parseJSON; }
})();
